package com.itheima.bigevent.interceptors;

import com.itheima.bigevent.property.JWTProperties;
import com.itheima.bigevent.utils.JwtUtil;
import com.itheima.bigevent.utils.ThreadLocalUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

/**
 * ClassName: LoginInterceptor
 * Package: com.itheima.bigevent.interceptors
 * Description:登录过滤器
 *
 * @Author: Zhang Peiyuan
 * @Create: 2024-08-19-18:37
 * @Version: v1.0
 */
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate rds;
    @Resource
    private JWTProperties jwtProperties;

    // 拦截器
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求头中的token
        String token = request.getHeader("Authorization");
        // 验证token
        try {
            // 解析jwt, map中存储的是键值对, 如果正确解析,则返回map, 否则抛出异常
            Map<String, Object> map = JwtUtil.parseToken(token, jwtProperties.getSecretKey());
            // 引入redis后, 就可以不再使用ThreadLocalUtil
            ThreadLocalUtil.set(map);

            // 从redis中获取token
            String token_redis = rds.opsForValue().get("token_" + map.get("id"));

            // 如果token已经失效,则返回的是null
            // 如果redis中储存的token和请求头中的token不一致
            if(null == token_redis || !token_redis.equals(token)){
                throw new RuntimeException("token已失效");
            }

            // 如果解析成功,则返回true, 放行
            return true;
        } catch (Exception e) {
            // 设置http响应码为 401
            response.setStatus(401);
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清空ThreadLocal中的数据
        ThreadLocalUtil.remove();
    }
}
